home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 417_01 / libftp / utils / ftptry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  8.6 KB  |  464 lines

  1. /*
  2.               Library for ftpd clients.(libftp)
  3.             Copyright by Oleg Orel
  4.              All rights reserved.
  5.             
  6. This  library is desined  for  free,  non-commercial  software  creation. 
  7. It is changeable and can be improved. The author would greatly appreciate 
  8. any  advises, new  components  and  patches  of  the  existing  programs.
  9. Commercial  usage is  also  possible  with  participation of it's author.
  10.  
  11.  
  12.  
  13. */
  14.  
  15. char intro[]="\
  16.             Ftptry - try transfer via FTP.\n\
  17.          Copyright by Oleg Orel is Reserved.\n\
  18. \n\
  19. This program is writen using \"libftp\".The main orientation for this\n\
  20. program  is  FTPing  via  bad-working  network. Many network  links are\n\
  21. down-up  switched  and  networks  are  broaken,   so  the  problem  of\n\
  22. transfering  large  files  exists.   The  main   method,  used  by this\n\
  23. software  is  repetition  until  successfull  transfer.  There are some\n\
  24. keys for  setting  repetition and timeout  intervals, modes of transfer\n\
  25. (binary and ascii), types of transfer  (get,put,directory). All options\n\
  26. will be described in usage, if the  program is started without them.\n\
  27. \n\
  28.   The libftp you may transfer from host lpuds.oea.ihep.su via ftp-anonymous.\n\
  29.   All question are sent to author via e-mail (orel@oea.ihep.su)\n\
  30.   ";  
  31.  
  32. #include <FtpLibrary.h>
  33. #include <sys/types.h>
  34. #include <sys/file.h>
  35. #include <signal.h>
  36. #include <setjmp.h>
  37.  
  38. char *gethost();
  39. char *date();
  40.  
  41.  
  42. char
  43.   *machine ="localhost",
  44.   *user="anonymous",
  45.   *password,
  46.   *file=NULL,
  47.   *localfile=NULL,
  48.   *progname="ftptry";
  49.  
  50.  
  51. #define log(x) fprintf(stderr,"Ftptry %s::%s\n",date(),x)
  52. #define DEBUG(x) (debug?log(x):0)
  53. #define USERNAME (getenv("USER")==NULL?getenv("LOGNAME"):getenv("USER"))
  54. STATUS my_abort();
  55. STATUS my_IO();
  56. jmp_buf stack;
  57. int counter=0;
  58. String tmp;
  59.  
  60. enum __type__ {ascii=1,binary};
  61. enum __bool__ {false,true};
  62. enum __mode__ {get=1,put,dir,multiget};
  63. enum __logmode__ {lm_tty,lm_file,lm_mail};
  64.  
  65. char *p;
  66. FTP *ftp=NULL;
  67. int type=ascii;
  68. int sleeptime=600;
  69. int debug=false;
  70. int mode=get;
  71. int timeout=180;
  72. int overwrite=false;
  73. int logmode=lm_tty;
  74. char *logfile=NULL;
  75. FILE *LIST=NULL;
  76. extern int errno;
  77.  
  78. main(int a,char **b)
  79. {
  80.   FILE *out,*in;
  81.   int c;
  82.   extern char *optarg;
  83.   extern int optind, opterr;
  84.   String PASSWORD;
  85.   
  86.   sprintf(password=PASSWORD,"%s@%s",
  87.       USERNAME,
  88.       gethost());
  89.  
  90.   progname=b[0];
  91.  
  92.   if ( a<2 ) usage();
  93.   
  94.   while((c=getopt(a,b,"GOIBDru:p:Pdbs:o:l:t:cm"))!=EOF)
  95.     {
  96.       switch(c)
  97.     {
  98.  
  99.     case 'G':
  100.       mode=multiget;
  101.       break;
  102.  
  103.     case 'O':
  104.  
  105.       overwrite=true;
  106.       break;
  107.       
  108.     case 'c':
  109.  
  110.       localfile="*STDOUT*";
  111.       break;
  112.       
  113.     case 'I':
  114.       fprintf(stderr,intro);
  115.       exit(0);
  116.         
  117.     case 'r':
  118.  
  119.       mode=put;
  120.       break;
  121.  
  122.     case 'd':
  123.  
  124.       mode=dir;
  125.       file=".";
  126.       break;
  127.  
  128.     case 't':
  129.  
  130.       timeout=atoi(optarg);
  131.       break;
  132.  
  133.     case 'l':
  134.  
  135.       localfile=optarg;
  136.       break;
  137.       
  138.     case 'D':
  139.  
  140.       debug=true;
  141.       break;
  142.       
  143.     case 'u':
  144.  
  145.       user=optarg;
  146.       break;
  147.  
  148.     case 'p':
  149.  
  150.       password=optarg;
  151.       break;
  152.  
  153.     case 'P':
  154.  
  155.       password=getpass("Password:");
  156.       break;
  157.       
  158.     case 'b':
  159.  
  160.       type=binary;
  161.       break;
  162.  
  163.     case 's':
  164.  
  165.       sleeptime=atoi(optarg);
  166.       break;
  167.  
  168.     case 'o':
  169.  
  170.       logmode=lm_file;
  171.       logfile=optarg;
  172.       break;
  173.       
  174.     case 'm':
  175.  
  176.       logmode=lm_mail;
  177.       break;
  178.       
  179.     case 'B':
  180.       
  181.       logmode=lm_file;
  182.       logfile=NULL;
  183.       break;
  184.  
  185.     default:
  186.  
  187.       usage();
  188.       
  189.     }
  190.       
  191.       
  192.     }
  193.  
  194.  
  195.   if (optind+1!=a) usage();
  196.  
  197.   if ((p=strchr(b[optind],':'))!=NULL)
  198.     {
  199.       file=p+1;
  200.       machine=b[optind];
  201.       *p=0;
  202.     }
  203.   else
  204.     {
  205.       file=b[optind];
  206.       machine="localhost";
  207.     }
  208.   
  209.  
  210.   switch(mode)
  211.     {
  212.  
  213.     case get:
  214.     case put:
  215.  
  216.       if (*file==0) file="README";
  217.       if (localfile==NULL) localfile=((p=strrchr(file,'/'))==NULL)?file:p+1;
  218.       break;
  219.  
  220.     case dir:
  221.  
  222.       if (*file==0) file=".";
  223.       if (localfile==NULL) localfile="*STDOUT*";
  224.       break;
  225.  
  226.     case multiget:
  227.  
  228.       if (*file==0) file="*";
  229.       if (localfile==NULL) localfile=".";
  230.       break;
  231.     }
  232.       
  233.   switch(logmode)
  234.     {
  235.  
  236.     case lm_file:
  237.       
  238.       if (fork()) quit("Suspending.....");
  239.       close(0);close(1);close(2);
  240.       if (logfile==NULL)
  241.     {
  242.       sprintf(tmp,"/tmp/ftptry-%s.XXXXXX",USERNAME);
  243.       mktemp(tmp);
  244.     }
  245.       else
  246.     strcpy(tmp,logfile);
  247.       
  248.       open(tmp,O_TRUNC|O_CREAT|O_WRONLY,0600);
  249.       dup(0);
  250.       dup(0);
  251.       break;
  252.  
  253.     case lm_mail:
  254.  
  255.       if (fork()) quit("Suspending.....");
  256.       close(0);close(1);close(2);
  257.  
  258.       sprintf(tmp,"mail %s",USERNAME);
  259.       popen(tmp,"w");
  260.       dup(0);dup(0);
  261.       break;
  262.     }
  263.   
  264.   
  265.   log((sprintf(tmp,"machine is %s, remote file is %s, local file is %s",
  266.          machine,file,localfile),tmp));
  267.   
  268.   loop();
  269.   
  270. }
  271.  
  272. loop()
  273. {
  274.   int r;
  275.  
  276.   counter=setjmp(stack);
  277.  
  278.   sprintf(tmp,"Start transfer %d's time",counter);
  279.   DEBUG(tmp);
  280.  
  281.   if (debug) FtplibDebug(FTP_noexit);
  282.   
  283.   if ((r=FtpLogin(&ftp,machine,user,password,NULL))<1)
  284.     {
  285.       loop2();
  286.     }
  287.   
  288.   FtpSetErrorHandler(ftp,my_abort);
  289.   FtpSetIOHandler(ftp,my_IO);
  290.   signal(SIGSEGV,loop2);
  291.   signal(SIGPIPE,loop2);
  292.   
  293.   if (type==binary)
  294.     FtpBinary(ftp);
  295.       
  296.   switch (mode)
  297.     {
  298.  
  299.     case get:
  300.  
  301.       FtpGetTimeout(ftp,file,localfile,timeout);
  302.       break;
  303.  
  304.     case put:
  305.  
  306.       FtpPutTimeout(ftp,localfile,file,timeout);
  307.       break;
  308.  
  309.     case dir:
  310.  
  311.       FtpRetrTimeout(ftp,"LIST %s",file,localfile,timeout);
  312.       break;
  313.  
  314.     case multiget:
  315.       domultiget();
  316.       break;
  317.       
  318.     }
  319.       
  320.   FtpBye(ftp);
  321.   
  322.   DEBUG("Transfer completed");
  323.   exit(0); /* Not erase, but loop calling from lopp2 too. */
  324. }
  325.  
  326. loop2()
  327. {
  328.   String tmp;
  329.   int i;
  330.   
  331.   DEBUG("Start pause");
  332.   for (i=3;i<64;i++) close(i);
  333.   sprintf(tmp,"Sleeping %d secs",sleeptime);
  334.   DEBUG(tmp);
  335.   sleep(sleeptime);
  336.   DEBUG("Try againg....");
  337.   longjmp(stack,counter+1);
  338. }
  339.  
  340. quit(char *s)
  341. {
  342.   extern int errno;
  343.   log(s);
  344.   exit(errno);
  345. }
  346.     
  347.  
  348. my_IO(FTP *ftp, int n, char *s)
  349. {
  350.   extern int errno;
  351.   DEBUG(strerror(errno));
  352.   loop2();
  353. }
  354.  
  355. my_abort(FTP *ftp, int n, char *s)
  356. {
  357.   log(s);
  358.   if ( abs(n) == 550 ) exit(-1) /* No access or not found */;
  359.   loop2();
  360. }
  361.  
  362.  
  363. domultiget()
  364. {
  365.   String list,localname,tmp_name;
  366.   
  367.   
  368.   sprintf(list,"/tmp/ftptry-%s-multiget.XXXXXX",USERNAME);
  369.   mktemp(list);
  370.  
  371.   FtpRetrTimeout(ftp,"NLST %s",file,list,timeout);
  372.  
  373.   if ((LIST=fopen(list,"r"))==NULL) quit(strerror(errno));
  374.  
  375.   while ( fgets (tmp, sizeof tmp, LIST) != NULL )
  376.     {
  377.       tmp[strlen(tmp)-1]=0;
  378.  
  379.       strcpy(localname,localfile);
  380.       strcat(localname,"/");
  381.       strcat(localname,(p=strrchr(tmp,'/'))==NULL?tmp:p+1);
  382.  
  383.       DEBUG(localname);
  384.  
  385.       strcpy(tmp_name,localname);
  386.       strcat(tmp_name,"...ftptry");
  387.  
  388.       if (access(localname,F_OK)==0 && !overwrite)
  389.     continue;
  390.  
  391.       FtpGetTimeout(ftp,tmp,tmp_name,timeout);
  392.  
  393.       link(tmp_name,localname);
  394.       unlink(tmp_name);
  395.     }
  396.  
  397.   fclose(LIST);
  398.   LIST=NULL;
  399.   return true;
  400. }
  401.  
  402. usage()
  403. {
  404.   fprintf(stderr,"\
  405. Usage: %s [optins] [host:file]\n\
  406.         (default host \"localhost\",\n\
  407.          default file \"README\" or \".\" in directory mode)\n\
  408. \n\
  409. Valid options:\n\
  410. \n\
  411.       -u user              default anonymous\n\
  412.       -p password          default %s\n\
  413.       -P                   inquire password from your terminal\n\
  414.       -l local_file        use only if remote and local file differ\n\
  415.       -c                   direct output to stdout(like cat)\n\
  416.       -r                   reverse mode, i.e. send file to remote host\n\
  417.       -d                   directory mode, remote file is patern or \"ls\" options\n\
  418.                            default output is stdout.\n\
  419.       -G                   multiget mode, file is patern for \"ls\" command\n\
  420.       -O                   Overwrite existing file(s). Use with -G to transfer all files\n\
  421.                            again at next try.\n\
  422.       -b                   binary transfer mode\n\
  423.       -s seconds           Retry interval, default 10 minutes\n\
  424.       -t seconds           Timeout, default 3 minutes\n\
  425.       -D                   Turn on debugging mode\n\
  426.       -B                   Run in background and direct output to\n\
  427.                            /tmp/ftptry-%s.XXXXXX\n\
  428.       -o file              Run in background and direct output\n\
  429.                            to file\n\
  430.       -m                   Send output to orel via e-mail\n\
  431.       -I                   Print short introduction\n\
  432. \n\
  433. Example:\n\
  434.       %s  -Dbs 300 garbo.uwasa.fi:ls-lR.Z\n\
  435.                    Retrive file ls-lR.Z from garbo.uwasa.fi in binary mode\n\
  436.                    trying to reestablish connection every 5 minutes\n\
  437.                    on failure. Print debugging information.\n\
  438. ",progname,password,USERNAME,USERNAME,progname);
  439.   exit(-1);
  440. }
  441.  
  442. char *gethost()
  443. {
  444.   static String tmp;
  445.   String tmp2;
  446.  
  447.   gethostname(tmp2,sizeof tmp2);
  448.  
  449.   strcpy(tmp,gethostbyname(tmp2)->h_name);
  450.   return tmp;
  451. }
  452.  
  453.  
  454. char *date()
  455. {
  456.   static String s;
  457.   time_t t=time((time_t *)0);
  458.  
  459.   strcpy(s,ctime(&t));
  460.   s[strlen(s)-1]=0;
  461.   return s;
  462. }
  463.  
  464.